<template>
  <div class="app-container">
    <el-form :model="queryForm" ref="queryForm" v-show="showSearch" :inline="true">
      <el-form-item label="角色名称" prop="name">
        <el-input
          v-model="queryForm.name"
          placeholder="请输入角色名称"
          clearable
          size="small"
          style="width: 200px"
          @keyup.enter.native="handleQuery"
        />
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select
          v-model="queryForm.status"
          placeholder="角色状态"
          clearable
          size="small"
          style="width: 200px"
        >
          <el-option
            v-for="item in statusOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <el-row :gutter="10" class="mb8">
      <el-col :span="1.5">
        <el-button
          type="primary"
          icon="el-icon-plus"
          size="mini"
          @click="handleAdd"
          v-has-perm="['system_role:add']"
        >新增
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="success"
          icon="el-icon-edit"
          size="mini"
          :disabled="single"
          @click="handleUpdate"
          v-has-perm="['system_role:edit']"
        >修改
        </el-button>
      </el-col>
      <el-col :span="1.5">
        <el-button
          type="danger"
          icon="el-icon-delete"
          size="mini"
          :disabled="multiple"
          @click="handleDelete"
          v-has-perm="['system_role:remove']"
        >删除
        </el-button>
      </el-col>
      <right-toolbar :showSearch.sync="showSearch" @queryTable="getPage"></right-toolbar>
    </el-row>

    <el-row :gutter="15">
      <!--角色管理-->
      <el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px">
        <el-card class="box-card" shadow="never">
          <div slot="header" class="clearfix">
            <span class="role-span">角色列表</span>
          </div>
          <el-table v-loading="loading" :header-cell-style="thStyleFun" :cell-style="cellStyleFun"
                    :data="roleList" @selection-change="handleSelectionChange"
                    @current-change="handleCurrentChange">
            <el-table-column type="selection" width="55"/>
            <el-table-column label="角色名称" prop="name" show-overflow-tooltip width="150"/>
            <el-table-column label="显示顺序" prop="orderNum" width="100"/>
            <el-table-column label="状态" width="100">
              <template slot-scope="scope">
                <el-switch
                  v-model="scope.row.status"
                  :active-value="0"
                  :inactive-value="1"
                  @change="handleStatusChange(scope.row)"
                ></el-switch>
              </template>
            </el-table-column>
            <el-table-column label="备注" prop="remark" width="300"></el-table-column>
            <el-table-column label="创建时间" prop="createTime" width="180"></el-table-column>
            <el-table-column label="操作" min-width="200px" class-name="small-padding fixed-width">
              <template slot-scope="scope">
                <el-button
                  size="mini"
                  type="detail"
                  icon="el-icon-view"
                  @click="handleUpdate(scope.row)"
                  v-has-perm="['system_role:detail']"
                >详情
                </el-button>
                <el-button
                  v-if="scope.row.level !== 1"
                  size="mini"
                  type="del"
                  icon="el-icon-delete"
                  @click="handleDelete(scope.row)"
                  v-has-perm="['system_role:remove']"
                >删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>

          <pagination
            v-show="total>0"
            :total="total"
            :page.sync="queryForm.cursor"
            :limit.sync="queryForm.limit"
            @pagination="getPage"
          />
        </el-card>
      </el-col>
      <!-- 菜单授权 -->
      <el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
        <el-card class="box-card" shadow="never" style="height: 700px;overflow: scroll">
          <div slot="header" class="clearfix">
            <el-tooltip class="item" effect="dark" content="选择指定角色分配菜单" placement="top">
              <span class="role-span">菜单分配</span>
            </el-tooltip>
            <el-button
              v-has-perm="['system_role:edit']"
              :disabled="!showButton"
              :loading="menuLoading"
              icon="el-icon-check"
              size="mini"
              style="float: right; padding: 6px 9px"
              type="primary"
              @click="handleRoleMenu"
            >保存
            </el-button>
          </div>
          <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand('1',$event)">展开/折叠</el-checkbox>
          <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll('1',$event)">全选/全不选</el-checkbox>
          <el-checkbox v-model="menuCheckStrictly" @change="handleCheckedTreeConnect('1',$event)">父子联动
          </el-checkbox>
          <el-tree
            ref="menuTable"
            :data="menuOptions"
            :props="defaultProps"
            :check-strictly="!menuCheckStrictly"
            empty-text="加载中，请稍后"
            show-checkbox
            node-key="id"
          />
        </el-card>
      </el-col>
    </el-row>

    <!-- 添加或修改角色配置对话框 -->
    <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="角色名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入角色名称"/>
        </el-form-item>
        <el-form-item label="角色顺序" prop="orderNum">
          <el-input-number v-model="form.orderNum" controls-position="right" :min="0"/>
        </el-form-item>
        <el-form-item label="状态">
          <el-radio-group v-model="form.status">
            <el-radio v-for="item in statusOptions"
                      :key="item.value" :label="item.value">
              {{ item.label }}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="菜单权限">
          <el-checkbox v-model="form.menuExpand" @change="handleCheckedTreeExpand('1',$event)">展开/折叠</el-checkbox>
          <el-checkbox v-model="form.menuNodeAll" @change="handleCheckedTreeNodeAll('1',$event)">全选/全不选</el-checkbox>
          <el-checkbox v-model="form.menuCheckStrictly" @change="handleCheckedTreeConnect('1',$event)">父子联动
          </el-checkbox>
          <el-tree
            class="tree-border"
            :data="form.menuOptions"
            show-checkbox
            ref="menuForm"
            node-key="id"
            :check-strictly="!form.menuCheckStrictly"
            empty-text="加载中，请稍后"
            :props="defaultProps"
          />
        </el-form-item>
        <el-form-item label="备注">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入内容"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <span v-has-perm="['system_role:add']">
          <el-button type="primary" v-if="title=='添加角色'" @click="submitForm">确 定
          </el-button>
        </span>
        <span v-has-perm="['system_role:edit']">
          <el-button type="primary" v-if="title=='修改角色'" @click="submitForm">确 定
          </el-button>
        </span>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import {addRole, assignRoleMenu, changeRoleStatus, delRole, getRole, getRoleById, updateRole} from "@/api/system/role";
import {getRoleMenuTree, getTreeMenu} from "@/api/system/menu";
import {cellStyleFun, thStyleFun} from "@/utils/common";

export default {
  name: "Role",
  data() {
    return {
      // 遮罩层
      loading: true,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 当前单选用户
      currentId: undefined,
      // 菜单保存是否展示
      showButton: false,
      // 菜单loading
      menuLoading: false,
      //父子联动
      menuCheckStrictly: false,
      // 角色表格数据
      roleList: [],
      // 弹出层标题
      title: "",
      // 是否显示弹出层
      open: false,
      // 是否显示弹出层（数据权限）
      openDataScope: false,
      menuExpand: false,
      menuNodeAll: false,
      // 状态
      statusOptions: [
        {value: 0, label: '启用'},
        {value: 1, label: '禁用'}
      ],
      // 菜单列表
      menuOptions: [],
      // 查询参数
      queryForm: {
        cursor: 1,
        limit: 20,
        name: undefined,
        status: undefined
      },
      // 表单参数
      form: {
        id: undefined,
        name: undefined,
        orderNum: 0,
        status: 0,
        menuIdList: [],
        menuCheckStrictly: true,
        menuExpand: false,
        menuNodeAll: false,
        // 菜单列表
        menuOptions: [],
        remark: undefined
      },
      defaultProps: {
        children: "children",
        label: "name"
      },
      // 表单校验
      rules: {
        name: [
          {required: true, message: "角色名称不能为空", trigger: "blur"}
        ],
        orderNum: [
          {required: true, message: "角色顺序不能为空", trigger: "blur"}
        ]
      }
    };
  },
  created() {
    this.getPage();
    this.getMenuTreeselect();
  },
  methods: {
    /** 查询角色列表 */
    getPage() {
      this.loading = true;
      getRole(this.queryForm).then(({result: res}) => {
        this.roleList = res.records
        this.total = res.total
        this.loading = false
      }).catch(err => {
        this.loading = false
      })
    },
    /** 查询菜单树结构 */
    getMenuTreeselect() {
      getTreeMenu().then(({result: res}) => {
        this.form.menuOptions = res
        this.menuOptions = res
      })
    },
    // 所有菜单节点数据
    getMenuAllCheckedKeys() {
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.menuForm.getCheckedKeys();
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.menuForm.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      return checkedKeys;
    },
    /** 根据角色ID查询菜单树结构 */
    getRoleMenuTreeselect(id) {
      return getRoleMenuTree(id).then(({result: res}) => {
        return res;
      })
    },
    // 角色状态修改
    async handleStatusChange(row) {
      let text = row.status === 0 ? "启用" : "停用";
      const confirm = await this.$confirm('确认要' + text + ' "  ' + row.name + '  "角色吗?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
      if (confirm != 'confirm') {
        row.status = row.status === 0 ? 1 : 0
        return this.$message.success('取消操作')
      }
      changeRoleStatus(row.id, row.status).then((res) => {
        this.$message.success(text + "成功");
      }).catch(err => {
        row.status = row.status === 0 ? 1 : 0
      })
    },
    // 取消按钮
    cancel() {
      this.open = false;
      this.reset();
    },
    // 取消按钮（数据权限）
    cancelDataScope() {
      this.openDataScope = false;
      this.reset();
    },
    // 表单重置
    reset() {
      this.resetForm("form");
      this.form = this.$options.data().form
      if (this.$refs.menuForm != undefined) {
        this.$refs.menuForm.setCheckedKeys([]);
      }
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryForm.cursor = 1;
      this.getPage();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.handleQuery();
    },
    // 多选框选中数据
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.id)
      this.single = selection.length != 1
      this.multiple = !selection.length
    },
    // 触发单选
    async handleCurrentChange(val) {
      if (val) {
        // 清空菜单的选中
        if (this.$refs.menuTable != undefined) {
          this.$refs.menuTable.setCheckedKeys([]);
        }
        // 保存当前的角色id
        this.currentId = val.id
        this.showButton = true
        let roleMenu = await this.getRoleMenuTreeselect(val.id);
        this.$nextTick(() => {
          this.$refs.menuTable.setCheckedKeys(roleMenu.checkIdList);
        });
      }
    },
    // 树权限（展开/折叠）
    handleCheckedTreeExpand(type, value) {
      let treeList = type == 1 ? this.menuOptions : this.form.menuOptions;
      for (let i = 0; i < treeList.length; i++) {
        if (type == 1) {
          this.$refs.menuTable.store.nodesMap[treeList[i].id].expanded = value;
        } else {
          this.$refs.menuForm.store.nodesMap[treeList[i].id].expanded = value;
        }
      }
    },
    // 树权限（全选/全不选）
    handleCheckedTreeNodeAll(type, value) {
      if (type == 1) {
        this.$refs.menuTable.setCheckedNodes(value ? this.menuOptions : []);
      } else {
        this.$refs.menuForm.setCheckedNodes(value ? this.form.menuOptions : []);
      }
    },
    // 树权限（父子联动）
    handleCheckedTreeConnect(type, value) {
      if (type == 1) {
        this.menuCheckStrictly = value ? true : false;
      } else {
        this.form.menuCheckStrictly = value ? true : false;
      }
    },
    /** 新增按钮操作 */
    async handleAdd() {
      this.reset();
      await this.getMenuTreeselect();
      this.open = true;
      this.title = "添加角色";
    },
    /** 修改按钮操作 */
    async handleUpdate(row) {
      this.reset();
      const id = row.id || this.ids
      let roleMenu = await this.getRoleMenuTreeselect(id);
      console.log(roleMenu)
      getRoleById(id).then(({result: res}) => {
        this.form = res
        this.open = true;
        this.form.menuOptions = roleMenu.menuTree
        this.$nextTick(() => {
          this.$refs.menuForm.setCheckedKeys(roleMenu.checkIdList);
        });
        this.title = "修改角色";
      });
    },
    /** 提交按钮 */
    submitForm() {
      if (this.validForm("form")) {
        if (this.form.id != undefined) {
          this.form.menuIdList = this.getMenuAllCheckedKeys();
          updateRole(this.form).then(res => {
            this.$message.success("修改成功");
            this.open = false;
            this.getPage();
          })
        } else {
          this.form.menuIdList = this.getMenuAllCheckedKeys();
          addRole(this.form).then(res => {
            this.$message.success("新增成功");
            this.open = false;
            this.getPage();
          })
        }
      }
    },
    /** 删除按钮操作 */
    async handleDelete(row) {
      const ids = row.id || this.ids;
      const confirm = await this.$confirm('是否确认删除角色编号为"' + ids + '"的数据项?', "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      });
      if (confirm != 'confirm') {
        return this.$message.success('取消操作')
      }
      delRole(ids).then((res) => {
        this.getPage();
        this.$message.success("删除成功");
      })
    },
    /*分配角色权限*/
    handleRoleMenu() {
      this.menuLoading = true
      // 目前被选中的菜单节点
      let checkedKeys = this.$refs.menuTable.getCheckedKeys();
      // 半选中的菜单节点
      let halfCheckedKeys = this.$refs.menuTable.getHalfCheckedKeys();
      checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys);
      assignRoleMenu(this.currentId, checkedKeys).then((res) => {
        this.menuLoading = false
        this.$message.success("分配成功");
      }).catch(err => {
        this.menuLoading = false
      })
    },
    // 表格居中 (html中使用需要先声明)
    thStyleFun,
    // 表格居中 (html中使用需要先声明)
    cellStyleFun
  }
};
</script>
